package org.javaboy.demo.service;

import org.javaboy.demo.dao.UserDao;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.function.Consumer;

public class UserService {

    UserDao userDao;

    PlatformTransactionManager transactionManager;

    TransactionTemplate transactionTemplate;

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    public void setTransactionManager(PlatformTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void transferMoney(String from, String to, Double money) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            /**
             * 这个方法就是在事务中执行，并且不需要返回值
             * @param status associated transaction status
             */
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                try {
                    userDao.minusMoney(from, money);
                    int i = 1 / 0;
                    userDao.addMoney(to, money);
                } catch (Exception e) {
                    //回滚
                    status.setRollbackOnly();
                    throw new RuntimeException(e);
                }
            }
        });
    }

    public void transferMoney2(String from, String to, Double money) {
        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
//        definition.setIsolationLevel(Isolation.READ_COMMITTED.value());
        //根据事务的定义，获取事务的状态，事务的定义其实就是事务的各种属性：比如超时时间、隔离级别、传播性。。。
        TransactionStatus status = transactionManager.getTransaction(definition);
        try {
            userDao.minusMoney(from, money);
            int i = 1 / 0;
            userDao.addMoney(to, money);
            //事务提交
            transactionManager.commit(status);
        } catch (Exception e) {
            //事务回滚
            transactionManager.rollback(status);
            throw new RuntimeException(e);
        }
    }
}
